package xman.mjava.concurrent.collection;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.PriorityBlockingQueue;

import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Queue {
    
    private static Logger logger = LoggerFactory.getLogger(Queue.class);
    
    private BlockingQueue<SuperEntiity> arrayBlockingQueue = new ArrayBlockingQueue<SuperEntiity>(100);
    
    private BlockingQueue<SuperEntiity> linkedBlockingQueue = new LinkedBlockingQueue<Queue.SuperEntiity>();

    private BlockingQueue<SuperEntiity> priorityBlockingQueue = new PriorityBlockingQueue<SuperEntiity>();
    
    class SuperEntiity implements Comparable<SuperEntiity> {

        protected Long priority;
        
        public Long getPriority() {
            return priority;
        }
        
        public void setPriority(Long priority) {
            this.priority = priority;
        }
        
        @Override
        public int compareTo(SuperEntiity o) { // ASC
            if (this.priority > o.priority)
                return 1;
            else if (this.priority == o.priority)
                return 0;
            else
                return -1;
        }
    }
    
    class InheritEntity extends SuperEntiity {
        
    }
    
    @Test
    public void arrayBlockingQueue() {
        SuperEntiity s1 = new InheritEntity();
        s1.setPriority(10L);
        SuperEntiity s2 = new InheritEntity();
        s2.setPriority(1L);
        SuperEntiity s3 = new InheritEntity();
        s3.setPriority(11L);
        arrayBlockingQueue.add(s1);
        arrayBlockingQueue.add(s2);
        arrayBlockingQueue.add(s3);
        while (true) {
            SuperEntiity obj = arrayBlockingQueue.poll();
            if (obj == null) {
                break;
            }
            logger.info("{}", obj.getPriority());
        }
    }
    
    @Test
    public void linkedBlockingQueue() {
        SuperEntiity s1 = new InheritEntity();
        s1.setPriority(10L);
        SuperEntiity s2 = new InheritEntity();
        s2.setPriority(12L);
        SuperEntiity s3 = new InheritEntity();
        s3.setPriority(11L);
        linkedBlockingQueue.add(s1);
        linkedBlockingQueue.add(s2);
        linkedBlockingQueue.add(s3);
        while (true) {
            SuperEntiity obj = linkedBlockingQueue.poll();
            if (obj == null) {
                break;
            }
            logger.info("{}", obj.getPriority());
        }
    }

    @Test
    public void priorityBlockingQueue() {
        SuperEntiity s1 = new InheritEntity();
        s1.setPriority(10L);
        SuperEntiity s2 = new InheritEntity();
        s2.setPriority(11L);
        priorityBlockingQueue.add(s1);
        priorityBlockingQueue.add(s2);
        while (true) {
            SuperEntiity obj = priorityBlockingQueue.poll(); // take is block method if empty,poll return null if empty

            if (obj == null) {
                break;
            }
            logger.info("{}", obj.getPriority());
        }
    }

}
